generic
   type cercle (<>) is private;
   type individu (<>) is private;
   type message (<>) is private;
   type mur (<>) is private;

   with function est_defini(M:mur;N:natural) return boolean is <>;
   with function auteur(M:mur;N:natural) return individu is <>;
   with function creer(I : individu) return mur is <>;
   with function ajouter(un_mur:mur;M : Message;Auteur : individu;N : Natural) return mur is <>;


   with function "=" (I1:individu;I2:individu)return boolean is <>;
   with function "<=" (I1:individu;I2:individu)return boolean is <>;
   with function "<" (I1:individu;I2:individu)return boolean is <>;

   with function "=" (I1:cercle;I2:cercle)return boolean is <>;
   with function "<=" (I1:cercle;I2:cercle)return boolean is <>;
   with function "<" (I1:cercle;I2:cercle)return boolean is <>;

package sigma is
   type modele is private;

   function creer return modele;
   function inscrire(C0:modele; I1:individu) return modele;
   function est_inscrit(C0:modele;I1:individu) return boolean;
   function nombre_inscrit(C0:modele) return natural;
   function ieme_inscrit(C0:modele;I:Natural) return individu;
   function bloquer (C0:modele; I1,I2: individu) return modele;
   function debloquer(C0:modele;I1,I2: individu) return modele;
   function est_bloque(C0:modele; I1,I2:individu) return boolean;

   function ajouter_cercle(C0:modele; I1: individu; C1:cercle) return modele;
   function retirer_cercle(C0:modele; I1: individu; C1:cercle) return modele;
   function est_cercle_de(C0:modele;I1:individu;C1:cercle) return boolean;
   function ieme_cercle(C0:modele;I1:individu;I:natural) return cercle;

   function ajouter_membre(C0:modele; I1: individu; C1:cercle; I2: individu) return modele;
   function retirer_membre(C0:modele; I1: individu; C1:cercle; I2: individu) return modele;
   function poster(C0:modele;I1:individu;C1:cercle;T: message) return modele;
   function commenter(C0: modele; I1:individu; I:Natural; T: message) return modele;

   function nombre_cercle_de(C0:modele;I1:individu) return natural;
   function est_membre_de(C0:modele;I1:individu;C1:cercle;I2:individu) return boolean;
   function nombre_membre_de(C0:modele;I1:individu;C1:cercle)return natural;
   function ieme_membre(C0:modele;I1:individu;C1:cercle;I:natural)return individu;

   function consulter(C0:modele;I1:individu) return Mur;
   function nombre_post(C0:modele) return Natural;

private

   type constructeur is (creer, inscrire, bloquer, debloquer,
                         ajouter_cercle, retirer_cercle, ajouter_membre,
                         retirer_membre, poster, commenter);
   type terme (selon : constructeur) is record
      case selon is
         when creer => null;
         when inscrire => inscrire_C0:modele;
            inscrire_I1: access individu;
         when bloquer => bloquer_C0:modele;
            bloquer_I1,bloquer_I2: access individu;
         when debloquer => debloquer_C0:modele;
            debloquer_I1,debloquer_I2: access individu;
         when ajouter_cercle => ajouter_cercle_C0:modele;
            ajouter_cercle_I1: access individu;
            ajouter_cercle_C1: access cercle;
         when retirer_cercle => retirer_cercle_C0:modele;
            retirer_cercle_I1: access individu;
            retirer_cercle_C1: access cercle;
         when ajouter_membre => ajouter_membre_C0:modele;
            ajouter_membre_I1: access individu;
            ajouter_membre_C1: access cercle;
            ajouter_membre_I2: access individu;
         when retirer_membre => retirer_membre_C0:modele;
            retirer_membre_I1: access individu;
            retirer_membre_C1: access cercle;
            retirer_membre_I2: access individu;
         when poster => poster_C0:modele;
            poster_I1: access individu;
            poster_C1: access cercle;
            poster_T: access message;
         when commenter => commenter_C0: modele;
            commenter_I1: access individu;
            commenter_I: Natural;
            commenter_T: access message;
      end case;
   end record;

   type modele is access terme;

end sigma;
